package com.danieltoms.gcSync.addressbook.screens;

import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.pim.PIMException;

import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;

import com.danieltoms.gcSync.GcSyncConstants;
import com.danieltoms.gcSync.GcSyncStore;
import com.danieltoms.gcSync.addressbook.widgets.MoveableEditFieldType;
import com.danieltoms.gcSync.addressbook.widgets.MoveableEmailAddressEditField;
import com.danieltoms.gcSync.addressbook.widgets.MoveableEditField;
import com.danieltoms.gcSync.contact.BBContact;
import com.danieltoms.gcSync.google.GoogleDataItem;
import com.danieltoms.gcSync.google.GoogleDataStore;
import com.danieltoms.gcSync.google.GoogleTypedField;

public class EditGmailInfo extends MainScreen
{
	BBContact _bbContact = null;
	GoogleDataItem _gdi = null;
	private int _emailStart = 0;
	public int _emailCount = 0;
	public int _phoneNumberCount = 0;
	public int _postalAddressCount = 0;
	public int _imCount = 0;
	private static String[] _homeWorkOtherTypes = { "Home", "Work", "Other" };
	private static String[] _primaryType = { "Primary" };

	private MenuItem _saveMenuItem = new MenuItem("Save", 1000000, 0)
	{
		public void run()
		{
			onSave();
		}
	};

	private MenuItem _addEmailMenuItem = new MenuItem("Add Email Address", 20, 0)
	{
		public void run()
		{
			onAddEmail();
		}
	};

	private MenuItem _addPhoneMenuItem = new MenuItem("Add Phone Number", 21, 0)
	{
		public void run()
		{
			onAddPhoneNumber();
		}
	};
	
	private MenuItem _addPostalAddressMenuItem = new MenuItem("Add Postal Address", 22, 0)
	{
		public void run()
		{
			onAddPostalAddress();
		}
	};

	private MenuItem _addIMMenuItem = new MenuItem("Add Instant Message", 23, 0)
	{
		public void run()
		{
			onAddInstantMessage();
		}
	};
	protected void makeMenu(Menu menu, int instance)
	{

		menu.add(_saveMenuItem);
		menu.addSeparator();
		menu.add(_addEmailMenuItem);
		menu.add(_addPostalAddressMenuItem);
		menu.add(_addPhoneMenuItem);
		menu.add(_addIMMenuItem);
		super.makeMenu(menu, instance);

	}

	public boolean onClose()
	{
		// UiApplication.getUiApplication().getActiveScreen().getScreenBelow().invalidate();
		UiApplication.getUiApplication().getActiveScreen().getScreenBelow().doPaint();
		return super.onClose();
	}

	protected boolean onSave()
	{
		printFields();
		
		
		Vector vector = saveGoogleTypedFields(_emailStart, _emailCount);
		_gdi.setEmails(vector);

		vector = saveGoogleTypedFields(this.getPhoneStart(), _phoneNumberCount);
		_gdi.setPhones(vector);		
		
		vector = saveGoogleTypedFields(this.getPostalAddressStart(), _postalAddressCount);
		_gdi.setAddresses(vector);

		vector = saveGoogleTypedFields(this.getInstantMessageStart(), _imCount);
		_gdi.setIms(vector);
	
		_gdi.setState(GoogleDataItem.BB_UPDATED);

		GoogleDataStore.instance().commit();
		GcSyncStore.instance().setContactListenerEnabled(false);

		try
		{
			_bbContact.getContact().commit();
		}
		catch (PIMException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		GcSyncStore.instance().setContactListenerEnabled(true);
		return true;
	}

	public void printFields()
    {
	    int i= 0;
		
		while(i<this.getFieldCount())
		{
			Object o = this.getField(i);
			log(i + " " + o.getClass().getName());
			i++;
		}
    }

	protected int getPhoneStart()
	{
		int start = _emailStart + (_emailCount * 2) + 2;
		log("getPhoneStart start: " + start);
		return start;
	}
	
	protected int getPostalAddressStart()
	{
		int start = getPhoneStart() + (_phoneNumberCount * 2) + 2;
		log("postal address start: " + start);
		return start;
	}

	protected int getInstantMessageStart()
	{

		int start = getPostalAddressStart() + (_postalAddressCount *2) + 2;
		log("im address start: " + start);
		return start;
	}
	
	
	private Vector saveGoogleTypedFields(int start, int fieldCount)
	{
		
		log(" start: " + start);
		log(" fieldCount: " + fieldCount);
		Vector retVal = new Vector();
		int stop = (fieldCount * 2) + start;
		if (start != 0)
		{

			while (start < stop)
			{
				Object o = (Object) this.getField(start);
				log(o.getClass().toString());
				EditField field = (EditField) o;
				String postalAddress = field.getText().trim();
				start++;
				ObjectChoiceField typeChoices = (ObjectChoiceField) this.getField(start);
				String typeChoice = (String) typeChoices.getChoice(typeChoices.getSelectedIndex());
				String choice = null;

				// TODO get rid of string literals
				if (typeChoice.equals("Home"))
					choice = GcSyncConstants.HOME_TYPE;
				else if (typeChoice.equals("Work"))
					choice = GcSyncConstants.WORK_TYPE;
				else if (typeChoice.equals("Other"))
					choice = GcSyncConstants.OTHER_TYPE;
				else if (typeChoice.equals("Home Fax"))
					choice = GcSyncConstants.HOME_FAX_TYPE;
				else if (typeChoice.equals("Work Fax"))
					choice = GcSyncConstants.WORK_FAX_TYPE;
				else if (typeChoice.equals("Mobile"))
					choice = GcSyncConstants.MOBILE_TYPE;
				else if (typeChoice.equals("Pager"))
					choice = GcSyncConstants.PAGER_TYPE;
				else if (typeChoice.equals("Google Talk"))
					choice = GcSyncConstants.IM_GOOGLE_TALK;
				else if (typeChoice.equals("AIM"))
					choice = GcSyncConstants.IM_AIM;
				else if (typeChoice.equals("ICQ"))
					choice = GcSyncConstants.IM_ICQ;
				else if (typeChoice.equals("Jabber"))
					choice = GcSyncConstants.IM_JABBER;
				else if (typeChoice.equals("MSN"))
					choice = GcSyncConstants.IM_MSN;
				else if (typeChoice.equals("Yahoo"))
					choice = GcSyncConstants.IM_YAHOO;
				
				GoogleTypedField gtf = new GoogleTypedField(postalAddress, choice);
				retVal.addElement(gtf);

				start++;

			}
			
			log("stopped at: " + start);

		}

		return retVal;
	}

	public EditGmailInfo(GoogleDataItem si, BBContact contact)
	{
		super(DEFAULT_CLOSE | DEFAULT_MENU);

		_gdi = si;
		_bbContact = contact;
		drawScreen();
	}

	protected void onExposed()
	{

	}

	private void drawScreen()
	{
		// todo remove this and just keep the handle to the items
		// and update
		// them as appropriate
		this.deleteAll();
		// add title
		setTitle(new LabelField("Edit Gmail:" + _bbContact.getGivenName(), LabelField.ELLIPSIS
				| LabelField.USE_ALL_WIDTH));

		if (_gdi != null)
		{
			this.add(new LabelField(_bbContact.getGivenName()));

			this.add(new LabelField(""));

			// do not change the order of these without adjusting the start method algoritims
			drawEmails();
			drawPhoneNumbers();
			drawAddresses();
			drawInstantMessaging();

		}
		else
			this.add(new RichTextField("Not synced", Field.NON_FOCUSABLE));

	}

	private void drawEmails()
	{

		this.add(new LabelField("Email Addresses"));
		this.add(new SeparatorField());
		_emailStart = this.getFieldCount();
		if (_gdi.getEmails() != null)
		{
			Enumeration emails = _gdi.getEmails().elements();

			if (emails != null)
			{
				while (emails.hasMoreElements())
				{
					GoogleTypedField email = (GoogleTypedField) emails.nextElement();
					createEmailEditField(email, 0);

				}

			}

		}

	}

	private void drawPhoneNumbers()
	{
		this.add(new LabelField("Phone Numers"));
		this.add(new SeparatorField());

		if (_gdi.getPhones() != null)
		{
			Enumeration phones = _gdi.getPhones().elements();
			if (phones != null)
			{
				while (phones.hasMoreElements())
				{
					GoogleTypedField email = (GoogleTypedField) phones.nextElement();
					createPhoneEditField(email, 0);
				}
			}
		}

	}
	
	private void drawAddresses()
	{
		this.add(new LabelField("Postal Addresses"));
		this.add(new SeparatorField());

		if (_gdi.getAddresses() != null)
		{
			Enumeration addresses = _gdi.getAddresses().elements();
			if (addresses != null)
			{
				while (addresses.hasMoreElements())
				{
					GoogleTypedField email = (GoogleTypedField) addresses.nextElement();
					createPostalAddressEditField(email, 0);

				}
			}
		}
	}
	
	private void drawInstantMessaging()
	{
		this.add(new LabelField("Instant Messaging"));
		this.add(new SeparatorField());

		if (_gdi.getIms() != null)
		{
			Enumeration ims = _gdi.getIms().elements();
			if (ims != null)
			{
				while (ims.hasMoreElements())
				{
					GoogleTypedField email = (GoogleTypedField) ims.nextElement();
					createInstantMessageEditField(email, 0);

				}
			}
		}
	}	

	private void createEmailEditField(GoogleTypedField email, int addIndex)
	{
		_emailCount++;
		
		ObjectChoiceField choiceField = null;

		if (email.getType() == null)
		{
			choiceField = new ObjectChoiceField(null, _primaryType, 0);
		}
		else
		{
			int choice = 0;
			if (email.getType().equals(GcSyncConstants.WORK_TYPE))
				choice = 1;
			else if (email.getType().equals(GcSyncConstants.OTHER_TYPE))
				choice = 2;

			choiceField = new ObjectChoiceField(null, _homeWorkOtherTypes, choice);

		}

		MoveableEmailAddressEditField emailField = new MoveableEmailAddressEditField(email, _emailStart);
		if (addIndex == 0)
		{
			this.add(emailField);
			this.add(choiceField);
		}
		else
		{
			this.insert(emailField, addIndex);
			this.insert(choiceField, addIndex + 1);
		}

	}

	private void createPostalAddressEditField(GoogleTypedField postalAddress, int addIndex)
	{

		_postalAddressCount++;
		
		ObjectChoiceField choiceField = null;

		int choice = 0;
		if (postalAddress.getType().equals(GcSyncConstants.WORK_TYPE))
			choice = 1;
		else if (postalAddress.getType().equals(GcSyncConstants.OTHER_TYPE))
			choice = 2;

		choiceField = new ObjectChoiceField(null, _homeWorkOtherTypes, choice);

		MoveableEditField addressField = new MoveableEditField(MoveableEditFieldType.POSTAL,postalAddress, this
				.getPostalAddressStart());

		if (addIndex == 0)
		{
			this.add(addressField);
			this.add(choiceField);
		}
		else
		{
			this.insert(addressField, addIndex);
			this.insert(choiceField, addIndex + 1);
		}

	}
	
	private static String[] _phoneTypes = { "Home", "Work", "Mobile", "Home Fax", "Work Fax", "Pager"};

	private void createPhoneEditField(GoogleTypedField phone, int addIndex)
	{

		_phoneNumberCount++;
		
		ObjectChoiceField choiceField = null;

		int choice = 0;
		if (phone.getType().equals(GcSyncConstants.WORK_TYPE))
			choice = 1;
		else if (phone.getType().equals(GcSyncConstants.MOBILE_TYPE))
			choice = 2;
		else if (phone.getType().equals(GcSyncConstants.HOME_FAX_TYPE))
			choice = 3;
		else if (phone.getType().equals(GcSyncConstants.WORK_FAX_TYPE))
			choice = 4;
		else if (phone.getType().equals(GcSyncConstants.PAGER_TYPE))
			choice = 5;	
		
		choiceField = new ObjectChoiceField(null, _phoneTypes, choice);

		MoveableEditField addressField = new MoveableEditField(MoveableEditFieldType.PHONE,phone, this
				.getPostalAddressStart());

		if (addIndex == 0)
		{
			this.add(addressField);
			this.add(choiceField);
		}
		else
		{
			this.insert(addressField, addIndex);
			this.insert(choiceField, addIndex + 1);
		}

	}
	
	private static String[] _imTypes = { "Google Talk", "AIM", "Yahoo", "MSN", "ICQ", "Jabber"};

	private void createInstantMessageEditField(GoogleTypedField im, int addIndex)
	{

		_imCount++;
		
		ObjectChoiceField choiceField = null;

		int choice = 0; // google talk
		
		if (im.getType().equals(GcSyncConstants.IM_AIM))
			choice = 1;
		else if (im.getType().equals(GcSyncConstants.IM_YAHOO))
			choice = 2;
		else if (im.getType().equals(GcSyncConstants.IM_MSN))
			choice = 3;
		else if (im.getType().equals(GcSyncConstants.IM_ICQ))
			choice = 4;	
		else if (im.getType().equals(GcSyncConstants.IM_JABBER))
			choice = 5;
		
		choiceField = new ObjectChoiceField(null, _imTypes, choice);

		MoveableEditField addressField = new MoveableEditField(MoveableEditFieldType.IM, im, this.getInstantMessageStart());

		if (addIndex == 0)
		{
			this.add(addressField);
			this.add(choiceField);
		}
		else
		{
			this.insert(addressField, addIndex);
			this.insert(choiceField, addIndex + 1);
		}

	}	
	
	protected void onAddEmail()
	{
		printFields();
		if (_emailCount == 0)
		{
			// just add as primary

			// we need to add the whole email section
			createEmailEditField(new GoogleTypedField("", null), _emailStart);

			this.setDirty(true);
		}
		else
		{
			int addIndex = getGoogleTypedFieldAddIndex(_emailStart, _emailCount);

			if (addIndex != -1)
			{
				createEmailEditField(new GoogleTypedField("", GcSyncConstants.HOME_TYPE), addIndex);

				this.setDirty(true);
			}

		}

	}

	protected void onAddPostalAddress()
	{
		printFields();
		if (_postalAddressCount==0)
		{
			createPostalAddressEditField(new GoogleTypedField("", GcSyncConstants.HOME_TYPE), this.getPostalAddressStart());

			this.setDirty(true);
		}
		else
		{
			int addIndex = getGoogleTypedFieldAddIndex(this.getPostalAddressStart(), _postalAddressCount);

			if (addIndex != -1)
			{
				createPostalAddressEditField(new GoogleTypedField("", GcSyncConstants.HOME_TYPE), addIndex);

				this.setDirty(true);
			}

		}
	}

	protected void onAddPhoneNumber()
	{
		printFields();
		if (_phoneNumberCount==0)
		{
			createPhoneEditField(new GoogleTypedField("", GcSyncConstants.HOME_TYPE), this.getPhoneStart());

			this.setDirty(true);
		}
		else
		{
			int addIndex = getGoogleTypedFieldAddIndex(this.getPhoneStart(), _phoneNumberCount);

			if (addIndex != -1)
			{
				createPhoneEditField(new GoogleTypedField("", GcSyncConstants.HOME_TYPE), addIndex);
				this.setDirty(true);
			}

		}
	}	
	
	protected void onAddInstantMessage()
	{
		printFields();
		if (_imCount==0)
		{
			createInstantMessageEditField(new GoogleTypedField("", GcSyncConstants.IM_GOOGLE_TALK), this.getInstantMessageStart());

			this.setDirty(true);
		}
		else
		{
			int addIndex = getGoogleTypedFieldAddIndex(this.getInstantMessageStart(), _imCount);

			if (addIndex != -1)
			{
				createInstantMessageEditField(new GoogleTypedField("", GcSyncConstants.IM_GOOGLE_TALK), addIndex);
				this.setDirty(true);
			}

		}
	}		
	
	protected int getGoogleTypedFieldAddIndex(int start, int fieldCount)
	{
		
		int addIndex = -1;

		int focusIndex = getFieldWithFocusIndex();

		log("field start: " + start);
		log("field count:" + fieldCount);

		
		int end = start + fieldCount * 2;

		EditField field = null;

		String fieldValue = null;

		// if we are adding address within the list range
		if ((start <= focusIndex) && (focusIndex < end))
		{

			// get whatever is selected
			Object current = this.getField(this.getFieldWithFocusIndex());

			// if its a choice field, the address is back one
			if (current instanceof ObjectChoiceField)
				current = this.getField(this.getFieldWithFocusIndex() - 1);

			// now get the address field and text
			field = (EditField) current;
			fieldValue = field.getText().trim();
		}

		String[] choices = null;

		int choice = 0;

		// if we aren't on the last field, and we are in the field range
		if (field != null && ((end - 2) != field.getIndex()))
		{
			choices = new String[] { "Add Last", "Add after " + fieldValue, "Cancel" };
			choice = Dialog.ask("Add Address?", choices, 1);
		}
		else
		{
			choices = new String[] { "Add Last", "Cancel" };
			choice = Dialog.ask("Add Address?", choices, 0);
		}

		// 0 add last
		// 1 add after, or cancel
		// 2 cancel
		log("choice: " + choice);

		if (choice == 2)
		{
			log("cancel");
		}
		else if (choices.length == 2 && choice == 1)
		{
			log("cancel");

		}
		else if (choice == 0)
		{
			log("add last");
			addIndex = end;

		}
		else if (choice == 1)
		{
			log("add after");
			addIndex = field.getIndex() + 2;
		}
		
		log("return addIndex: "+addIndex);

		return addIndex;
	}

	private void log(String msg)
	{
		System.out.println(msg);
	}

	public void deleteEditField(MoveableEditFieldType field)
    {
	    if(field.getType()==MoveableEditFieldType.EMAIL)
	    	_emailCount--;
	    else if(field.getType()==MoveableEditFieldType.POSTAL)	  
		    _postalAddressCount--;
	    else if(field.getType()==MoveableEditFieldType.PHONE)	  
		    _phoneNumberCount--;	
	    else if(field.getType()==MoveableEditFieldType.IM)	  
		    _imCount--;	
    }

}
